package com.tarena.lbs.coupon.service.handler.issue;

import com.tarena.lbs.base.protocol.model.Result;
import com.tarena.lbs.coupon.api.pojo.param.UserCouponsParam;
import com.tarena.lbs.coupon.dao.repository.CouponCodeRepository;
import com.tarena.lbs.coupon.dao.repository.CouponRepository;
import com.tarena.lbs.coupon.dao.repository.StockRepository;
import com.tarena.lbs.coupon.dao.repository.UserCouponsRepository;
import com.tarena.lbs.coupon.enums.CouponIssueChannel;
import com.tarena.lbs.coupon.enums.UserCouponStatus;
import com.tarena.lbs.coupon.enums.UserCouponStatusEnum;
import com.tarena.lbs.coupon.pojo.po.CouponCodePO;
import com.tarena.lbs.coupon.pojo.po.CouponPO;
import com.tarena.lbs.coupon.pojo.po.UserCouponsPO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @className: CouponIssuerServiceImpl
 * @author: Feng-hongliang
 * @date: 2025/10/10 15:08
 * @Version: 1.0
 * @description: 优惠券发行处理
 * <p>
 * 这个是优惠券发放类 主要提供：
 * 优惠券发放
 * 用户主动领取优惠券
 * 优惠券领取列表
 * 优惠券被领取后的处理-例如库存扣减等
 * <p>
 */
@Slf4j
@Component
public class CouponIssuerHandler {

    final private CouponCodeRepository couponCodeRepository;
    final private CouponRepository couponRepository;
    final private UserCouponsRepository userCouponsRepository;
    final private StockRepository stockRepository;

    public CouponIssuerHandler(CouponCodeRepository couponCodeRepository, CouponRepository couponRepository, UserCouponsRepository userCouponsRepository, StockRepository stockRepository) {
        this.couponCodeRepository = couponCodeRepository;
        this.couponRepository = couponRepository;
        this.userCouponsRepository = userCouponsRepository;
        this.stockRepository = stockRepository;
    }

    /**
     * 用户主动领取优惠券
     * <p>
     * 用户主动领取优惠券
     * 不检查用户是否已领取等业务校验逻辑
     *
     * @param param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> UserIssueCoupon(UserCouponsParam param) {
        log.info("开始给用户新增优惠券数据");
        if (param.getActivityId() == null) {
            log.error("用户优惠券参数验证失败: {}", "活动ID不能为空");
            log.warn("用户优惠券参数验证活动ID为空, 即将生成假数据活动ID：110");
//            TODO:目前还不确定这个活动ID为什么会有，先假数据
            param.setActivityId(110);
        }
        try {
//            不需要判断数据，因为已经验证完毕
            CouponPO couponPO = couponRepository.findById(param.getCouponId());

            // 生成并保存券码
            String couponCode = generateCouponCode();
            log.debug("本息生成优惠券码：{}", couponCode);
            CouponCodePO couponCodePO = createCouponCode(param, couponCode);
            couponCodeRepository.insert(couponCodePO);

            // 创建用户领券记录
            UserCouponsPO userCouponsPO = createUserCoupon(param, couponPO, couponCode);
            userCouponsRepository.insert(userCouponsPO);

            // 5. 扣减库存
            stockRepository.deductStock(param.getCouponId());

            return Result.success();
        } catch (Exception e) {
            log.error("用户领取优惠券失败，param={}", param, e);
//            TODO： 异常处理
            throw new RuntimeException("用户领取优惠券失败", e);
        }
    }

    /**
     * 生成唯一优惠券码, 暂时用UUID代替
     *
     * @return 优惠券码
     */
    private String generateCouponCode() {
        return java.util.UUID.randomUUID().toString().replace("-", "").toUpperCase();
    }

    /**
     * 创建券码表实体
     *
     * @param param      用户领券时携带的参数
     * @param couponCode 优惠券码
     * @return 对应的券码表实体
     */
    private CouponCodePO createCouponCode(UserCouponsParam param, String couponCode) {
        CouponCodePO couponCodePO = new CouponCodePO();
        couponCodePO.setCouponCode(couponCode);
        couponCodePO.setCouponId(param.getCouponId());
        couponCodePO.setBusinessId(param.getShopId());
        couponCodePO.setStatus(1);
        couponCodePO.setCreateAt(new Date());
        return couponCodePO;
    }

    /**
     * 创建用户领券表的实体
     *
     * @param param      用户领券时携带的参数
     * @param couponPO   优惠券信息PO实体
     * @param couponCode 优惠券码
     * @return 用户领券表实体
     */
    private UserCouponsPO createUserCoupon(UserCouponsParam param, CouponPO couponPO, String couponCode) {
        UserCouponsPO userCouponsPO = new UserCouponsPO();
//        TODO: 优惠券类型，面额的 NullPointerException，待代码整合获取数据后再完善
        userCouponsPO.setUserId(param.getUserId());
        userCouponsPO.setCouponId(param.getCouponId());
//        用户刚领取，状态一般为待使用，一般不会是禁用回收等状态
        userCouponsPO.setCouponType(UserCouponStatus.UNUSED.getCode());
//        目前无法判断用户接口从哪进入，由于用户端只有微信小程序，所以现在统一使用微信小程序接口
        userCouponsPO.setReceiveChannel(CouponIssueChannel.WEIXING_MINI_PROGRAM.getCode());
        userCouponsPO.setCreateAt(new Date());
        userCouponsPO.setActivityId(param.getActivityId());
        userCouponsPO.setCouponCode(couponCode);
        userCouponsPO.setCouponType(couponPO.getCouponType());
        userCouponsPO.setCouponValue(couponPO.getDiscountValue());
        userCouponsPO.setShopId(param.getShopId());
//        状态修改
        userCouponsPO.setStatus(UserCouponStatusEnum.UNUSED.getCode());
        return userCouponsPO;
    }

}